"""
应用配置设置
"""

import os
from typing import List
from pydantic import Field
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    """应用配置类"""

    # 应用基本配置
    app_name: str = Field(default="测试用例生成系统", env="APP_NAME")
    app_version: str = Field(default="1.0.0", env="APP_VERSION")
    debug: bool = Field(default=False, env="DEBUG")
    host: str = Field(default="0.0.0.0", env="HOST")
    port: int = Field(default=8000, env="PORT")

    # 数据库配置
    database_url: str = Field(default="test_cases.db", env="DATABASE_URL")
    database_echo: bool = Field(default=False, env="DATABASE_ECHO")

    # LLM API配置 - 通用配置
    llm_provider: str = Field(default="openai", env="LLM_PROVIDER")  # 模型提供商
    llm_api_url: str = Field(default="", env="LLM_API_URL")
    llm_api_key: str = Field(default="", env="LLM_API_KEY")
    llm_model: str = Field(default="gpt-3.5-turbo", env="LLM_MODEL")
    llm_timeout: int = Field(default=120, env="LLM_TIMEOUT")  # 已弃用，使用智能超时
    llm_max_tokens: int = Field(default=4000, env="LLM_MAX_TOKENS")
    llm_temperature: float = Field(default=0.3, env="LLM_TEMPERATURE")

    # OpenAI配置
    openai_api_key: str = Field(default="", env="OPENAI_API_KEY")
    openai_api_url: str = Field(
        default="https://api.openai.com/v1/chat/completions", env="OPENAI_API_URL")
    openai_model: str = Field(default="gpt-3.5-turbo", env="OPENAI_MODEL")

    # DeepSeek配置
    deepseek_api_key: str = Field(default="", env="DEEPSEEK_API_KEY")
    deepseek_api_url: str = Field(
        default="https://api.deepseek.com/v1/chat/completions", env="DEEPSEEK_API_URL")
    deepseek_model: str = Field(default="deepseek-chat", env="DEEPSEEK_MODEL")

    # Gemini配置
    gemini_api_key: str = Field(default="", env="GEMINI_API_KEY")
    gemini_model: str = Field(default="gemini-pro", env="GEMINI_MODEL")

    # 豆包配置
    doubao_api_key: str = Field(default="", env="DOUBAO_API_KEY")
    doubao_api_url: str = Field(
        default="https://ark.cn-beijing.volces.com/api/v3/chat/completions", env="DOUBAO_API_URL")
    doubao_model: str = Field(default="doubao-pro-4k", env="DOUBAO_MODEL")

    # Claude配置
    claude_api_key: str = Field(default="", env="CLAUDE_API_KEY")
    claude_model: str = Field(
        default="claude-3-sonnet-20240229", env="CLAUDE_MODEL")

    # 智谱AI配置
    zhipu_api_key: str = Field(default="", env="ZHIPU_API_KEY")
    zhipu_api_url: str = Field(
        default="https://open.bigmodel.cn/api/paas/v4/chat/completions", env="ZHIPU_API_URL")
    zhipu_model: str = Field(default="glm-4", env="ZHIPU_MODEL")

    # 本地模型配置
    local_api_key: str = Field(default="local", env="LOCAL_API_KEY")
    local_api_url: str = Field(
        default="http://localhost:11434/v1/chat/completions", env="LOCAL_API_URL")
    local_model: str = Field(default="llama2", env="LOCAL_MODEL")

    # 智能超时配置
    smart_timeout_enabled: bool = Field(
        default=True, env="SMART_TIMEOUT_ENABLED")
    base_timeout_small: int = Field(
        default=360, env="BASE_TIMEOUT_SMALL")  # 小需求基础超时（秒）
    base_timeout_medium: int = Field(
        default=480, env="BASE_TIMEOUT_MEDIUM")  # 中等需求基础超时
    base_timeout_large: int = Field(
        default=600, env="BASE_TIMEOUT_LARGE")  # 大需求基础超时
    base_timeout_xlarge: int = Field(
        default=720, env="BASE_TIMEOUT_XLARGE")  # 超大需求基础超时
    base_timeout_xxlarge: int = Field(
        default=900, env="BASE_TIMEOUT_XXLARGE")  # 极大需求基础超时
    max_timeout_limit: int = Field(
        default=1800, env="MAX_TIMEOUT_LIMIT")  # 最大超时限制（30分钟）
    retry_timeout_multiplier: float = Field(
        default=1.5, env="RETRY_TIMEOUT_MULTIPLIER")  # 重试超时倍数

    # 推理模型专用配置
    reasoning_model_max_tokens: int = Field(
        default=8000, env="REASONING_MODEL_MAX_TOKENS")
    reasoning_model_temperature: float = Field(
        default=0.2, env="REASONING_MODEL_TEMPERATURE")

    # 推理模型专用超时配置（推理模型需要更长时间）
    reasoning_model_base_timeout_small: int = Field(
        default=300, env="REASONING_MODEL_BASE_TIMEOUT_SMALL")
    reasoning_model_base_timeout_medium: int = Field(
        default=450, env="REASONING_MODEL_BASE_TIMEOUT_MEDIUM")
    reasoning_model_base_timeout_large: int = Field(
        default=600, env="REASONING_MODEL_BASE_TIMEOUT_LARGE")
    reasoning_model_base_timeout_xlarge: int = Field(
        default=900, env="REASONING_MODEL_BASE_TIMEOUT_XLARGE")
    reasoning_model_base_timeout_xxlarge: int = Field(
        default=1200, env="REASONING_MODEL_BASE_TIMEOUT_XXLARGE")
    reasoning_model_max_timeout_limit: int = Field(
        default=1800, env="REASONING_MODEL_MAX_TIMEOUT_LIMIT")

    # 手动指定推理模型（用于未来模型或特殊模型）
    manual_reasoning_models: str = Field(
        default="", env="MANUAL_REASONING_MODELS")  # 逗号分隔的模型名称列表

    # 测试用例生成配置
    max_test_cases_per_batch: int = Field(
        default=50, env="MAX_TEST_CASES_PER_BATCH")
    min_test_cases_threshold: int = Field(
        default=10, env="MIN_TEST_CASES_THRESHOLD")
    auto_continue_enabled: bool = Field(
        default=True, env="AUTO_CONTINUE_ENABLED")

    # 大批量生成配置
    max_chars_per_module: int = Field(
        default=800, env="MAX_CHARS_PER_MODULE")  # 每个模块最大字符数
    batch_delay_seconds: float = Field(
        default=1.0, env="BATCH_DELAY_SECONDS")  # 批次间延迟（秒）

    # 性能优化配置
    max_concurrent_modules: int = Field(
        default=3, env="MAX_CONCURRENT_MODULES")  # 最大并发模块数
    enable_concurrent_processing: bool = Field(
        default=False, env="ENABLE_CONCURRENT_PROCESSING")  # 启用并发处理
    enable_result_cache: bool = Field(
        default=False, env="ENABLE_RESULT_CACHE")  # 启用结果缓存
    cache_similarity_threshold: float = Field(
        default=0.8, env="CACHE_SIMILARITY_THRESHOLD")  # 缓存相似度阈值
    cache_expire_hours: int = Field(
        default=24, env="CACHE_EXPIRE_HOURS")  # 缓存过期时间（小时）
    max_retries: int = Field(
        default=3, env="MAX_RETRIES")  # 最大重试次数
    enable_smart_retry: bool = Field(
        default=False, env="ENABLE_SMART_RETRY")  # 启用智能重试

    # 动态参数优化配置
    dynamic_max_tokens: bool = Field(
        default=False, env="DYNAMIC_MAX_TOKENS")  # 动态调整最大令牌数
    min_max_tokens: int = Field(
        default=1000, env="MIN_MAX_TOKENS")  # 最小最大令牌数
    max_max_tokens: int = Field(
        default=4000, env="MAX_MAX_TOKENS")  # 最大最大令牌数

    # 智能提示词配置
    enable_smart_prompts: bool = Field(
        default=False, env="ENABLE_SMART_PROMPTS")  # 启用智能提示词
    prompt_speed_priority: bool = Field(
        default=False, env="PROMPT_SPEED_PRIORITY")  # 提示词速度优先
    prompt_auto_selection: bool = Field(
        default=False, env="PROMPT_AUTO_SELECTION")  # 提示词自动选择

    # 数据清理配置
    data_retention_days: int = Field(default=30, env="DATA_RETENTION_DAYS")
    auto_cleanup_enabled: bool = Field(
        default=True, env="AUTO_CLEANUP_ENABLED")
    cleanup_time: str = Field(default="02:00", env="CLEANUP_TIME")

    # 日志配置
    log_level: str = Field(default="INFO", env="LOG_LEVEL")
    log_file: str = Field(default="logs/app.log", env="LOG_FILE")
    log_max_size: int = Field(default=10485760, env="LOG_MAX_SIZE")  # 10MB
    log_backup_count: int = Field(default=5, env="LOG_BACKUP_COUNT")

    # 安全配置
    secret_key: str = Field(default="your-secret-key-here", env="SECRET_KEY")
    cors_origins: List[str] = Field(default=["*"], env="CORS_ORIGINS")

    # 文件上传配置
    upload_max_size: int = Field(
        default=52428800, env="UPLOAD_MAX_SIZE")  # 50MB，支持大文件
    upload_allowed_extensions: List[str] = Field(
        default=[".txt", ".doc", ".docx", ".pdf", ".md"],
        env="UPLOAD_ALLOWED_EXTENSIONS"
    )
    # 文档内容处理配置
    max_content_length: int = Field(
        default=100000, env="MAX_CONTENT_LENGTH")  # 最大内容长度100K字符
    enable_large_file_processing: bool = Field(
        default=True, env="ENABLE_LARGE_FILE_PROCESSING")  # 启用大文件处理

    # Excel导出配置
    excel_max_rows: int = Field(default=10000, env="EXCEL_MAX_ROWS")
    excel_template_path: str = Field(
        default="templates/test_case_template.xlsx", env="EXCEL_TEMPLATE_PATH")

    # 性能配置
    max_workers: int = Field(default=4, env="MAX_WORKERS")
    request_timeout: int = Field(default=300, env="REQUEST_TIMEOUT")  # 5分钟

    # 监控配置
    enable_metrics: bool = Field(default=True, env="ENABLE_METRICS")
    metrics_port: int = Field(default=9090, env="METRICS_PORT")

    def get_model_config(self) -> dict:
        """获取当前配置的模型参数"""
        provider = self.llm_provider.lower()

        # 优先使用通用配置，如果没有则使用特定提供商配置
        if provider == "openai":
            return {
                "provider": "openai",
                "api_key": self.llm_api_key or self.openai_api_key,
                "api_url": self.llm_api_url or self.openai_api_url,
                "model": self.llm_model or self.openai_model
            }
        elif provider == "deepseek":
            return {
                "provider": "deepseek",
                "api_key": self.llm_api_key or self.deepseek_api_key,
                "api_url": self.llm_api_url or self.deepseek_api_url,
                "model": self.llm_model or self.deepseek_model
            }
        elif provider == "gemini":
            return {
                "provider": "gemini",
                "api_key": self.llm_api_key or self.gemini_api_key,
                "api_url": None,
                "model": self.llm_model or self.gemini_model
            }
        elif provider == "doubao":
            return {
                "provider": "doubao",
                "api_key": self.llm_api_key or self.doubao_api_key,
                "api_url": self.llm_api_url or self.doubao_api_url,
                "model": self.llm_model or self.doubao_model
            }
        elif provider == "claude":
            return {
                "provider": "claude",
                "api_key": self.llm_api_key or self.claude_api_key,
                "api_url": None,
                "model": self.llm_model or self.claude_model
            }
        elif provider == "zhipu":
            return {
                "provider": "zhipu",
                "api_key": self.llm_api_key or self.zhipu_api_key,
                "api_url": self.llm_api_url or self.zhipu_api_url,
                "model": self.llm_model or self.zhipu_model
            }
        elif provider == "local":
            return {
                "provider": "local",
                "api_key": self.llm_api_key or self.local_api_key,
                "api_url": self.llm_api_url or self.local_api_url,
                "model": self.llm_model or self.local_model
            }
        else:
            # 默认使用OpenAI兼容配置
            return {
                "provider": "openai",
                "api_key": self.llm_api_key,
                "api_url": self.llm_api_url,
                "model": self.llm_model
            }

    class Config:
        env_file = ".env"
        env_file_encoding = "utf-8"
        case_sensitive = False
        extra = "ignore"  # 忽略额外的配置项，避免验证错误

    def get_database_path(self) -> str:
        """获取数据库文件路径"""
        if self.database_url.startswith("sqlite:///"):
            return self.database_url[10:]  # 移除 sqlite:/// 前缀
        return self.database_url

    def get_log_dir(self) -> str:
        """获取日志目录"""
        return os.path.dirname(self.log_file)

    def ensure_directories(self):
        """确保必要的目录存在"""
        directories = [
            self.get_log_dir(),
            "uploads",
            "exports",
            "templates"
        ]

        for directory in directories:
            if directory and not os.path.exists(directory):
                os.makedirs(directory, exist_ok=True)

    def is_development(self) -> bool:
        """判断是否为开发环境"""
        return self.debug

    def is_production(self) -> bool:
        """判断是否为生产环境"""
        return not self.debug


def get_settings() -> Settings:
    """获取配置实例"""
    settings = Settings()
    settings.ensure_directories()
    return settings


# 导出配置实例
settings = get_settings()
